window.onload = () => {
  const canvas = document.querySelector("#canvas");
  canvas.height = window.innerHeight;
  canvas.width = window.innerWidth;
  const ctx = canvas.getContext("2d");

  class Particle {
    constructor(effect, x, y, color) {
      this.effect = effect;
      this.x = x; // Math.random() * this.effect.width;
      this.y = y; // Math.random() * this.effect.height;
      this.originX = Math.floor(x);
      this.originY = Math.floor(y);
      this.color = color;
      this.size = this.effect.gap; // this.effect.gap - 1;
      this.vx = 0; // Math.random() * 2 - 1;
      this.vy = 0; // Math.random() * 2 - 1;
    }

    draw(context) {
      context.fillStyle = this.color;
      context.fillRect(this.x, this.y, this.size, this.size);
    }

    update() {
      this.x += this.vx;
      this.y += this.vy;
    }
  }

  class Effect {
    constructor(width, height) {
      this.width = width;
      this.height = height;
      this.particlesArray = [];

      this.img = document.querySelector("#img");
      this.centerX = this.width / 2;
      this.centerY = this.height / 2;
      this.x = this.centerX - this.img.width / 2;
      this.y = this.centerY - this.img.height / 2;
      this.gap = 2; // 间隔多少取一个像素,这是看性能如何了，性能好，就取 1
    }

    init(context) {
      context.drawImage(this.img, this.x, this.y);
      const { width, height, gap } = this;
      // 取出图像的像素点
      const pixels = context.getImageData(0, 0, width, height).data;

      // 循环过滤出需要的像素点
      for (let y = 0; y < height; y += gap) {
        for (let x = 0; x < width; x += gap) {
          const index = (y * width + x) * 4; // 乘 4, 是因为，rgba 组成一个像素颜色
          const r = pixels[index];
          const g = pixels[index + 1];
          const b = pixels[index + 2];
          const a = pixels[index + 3];
          // 符合要求的当前位置的像素颜色
          const color = `rgb(${r}, ${g}, ${b})`;
          // 不是透明的就取出来
          if (a > 0) {
            this.particlesArray.push(new Particle(this, x, y, color));
          }
        }
      }
    }

    draw(context) {
      this.particlesArray.forEach((particle) => particle.draw(context));
    }

    update() {
      this.particlesArray.forEach((particle) => particle.update());
    }
  }

  const effect = new Effect(canvas.width, canvas.height);
  effect.init(ctx);

  function animate() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    effect.draw(ctx);
    effect.update();
    requestAnimationFrame(animate);
  }

  animate();
};
